﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Engine;
using System.Net;
using Microsoft.Xna.Framework;
using Engine.Objects;
using System.Net.NetworkInformation;
namespace NOWAOnline.Scenes.LoginScene
{
    public unsafe class LoginScene : Engine.Scene.BaseScene
    {
        LoginForm loginform;
        ELUA eula;
        int cServ = 0;
        SelectServer serverSelect;
        TomShane.Neoforce.Controls.Label LoginServerState;
        Engine.Client.BaseClient client;
        public static string NameScene { get { return "LoginScene"; } }
        public LoginScene(NOWAEngine _game)
            : base(_game, NameScene, true)
        {
            Engine.Voxel.Materials.init();
            for (int i = 0; i < 1; i++)
            {
                for (int x = 0; x < 1; x++)
                {
                    //Engine.Voxel.VoxelObject tmp = new Engine.Voxel.VoxelObject(_game, "v" + (i * 10 + x), new Vector3(x * 1, 0, i * 1), 0.1f,
                    // Quaternion.Identity
                    //  );
                    Engine.Objects.BaseDrawObject tmp = new Engine.Objects.BaseDrawObject(_game, "m" + (i * 10 + x), new Vector3(x * 1, 0, i * 1),(Vector3.One),
                    Quaternion.Identity
                     );
                    tmp.LoadContent();
                    addObject(tmp);
                }
            }
          
            DEFAULTCamera cam = (DEFAULTCamera)(((Engine.NOWAEngine)Game).Manager.GetComponent("CameraManager")).GetMaincamera();
            cam.LookAt(new Vector3(5, 5, 5));
            cam.Position = new Vector3(0, 0, -10);
            backColor = Color.CornflowerBlue;
        }
        public override void Initialize()
        {
            base.Initialize();
            loginform = new LoginForm(GUIManager);
            loginform.Okbtn.Click += new TomShane.Neoforce.Controls.EventHandler(Okbtn_Click);
            loginform.Cancelbtn.Click += new TomShane.Neoforce.Controls.EventHandler(Cancelbtn_Click);
            loginform.PassBox.Click += new TomShane.Neoforce.Controls.EventHandler(PassBox_Click);
            loginform.LoginBox.Click += new TomShane.Neoforce.Controls.EventHandler(LoginBox_Click);
            loginform.Init();
            eula = new ELUA(GUIManager);
            eula.okBtn.Click += new TomShane.Neoforce.Controls.EventHandler(okBtn_Click);
            eula.CancelBtn.Click += new TomShane.Neoforce.Controls.EventHandler(CancelBtn_Click);
            eula.Init();
            LoginServerState = new TomShane.Neoforce.Controls.Label(GUIManager);
            LoginServerState.Width = 200;
            LoginServerState.Height = 23;
            LoginServerState.Text = "Login server OFFLINE";
            LoginServerState.TextColor = Microsoft.Xna.Framework.Color.Red;
            LoginServerState.Top = 0;
            LoginServerState.Left = 0;

            serverSelect = new SelectServer(GUIManager);
            serverSelect.Init();
            serverSelect.ServerOk.Click += new TomShane.Neoforce.Controls.EventHandler(ServerOk_Click);
            serverSelect.ServerCancel.Click += new TomShane.Neoforce.Controls.EventHandler(ServerCancel_Click);

            GUIManager.Add(serverSelect);
            GUIManager.Add(loginform);
            GUIManager.Add(eula);
            GUIManager.Add(LoginServerState);
            eula.Hide();
            serverSelect.Hide();
            //backColor = Microsoft.Xna.Framework.Color.Black;
            TryConnectLogin();
        }

        void ServerCancel_Click(object sender, TomShane.Neoforce.Controls.EventArgs e)
        {
            client.ssesionKey = 0;
            eula.Hide();
            loginform.Show();
        }
        bool pingServer(IPAddress m_IP)
        {
            
            Ping pingSender = new Ping();
            PingOptions options = new PingOptions();

            // Use the default Ttl value which is 128,
            // but change the fragmentation behavior.
            options.DontFragment = true;

            // Create a buffer of 32 bytes of data to be transmitted.
            string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
            byte[] buffer = Encoding.ASCII.GetBytes(data);
            int timeout = 120;
            PingReply reply = pingSender.Send(m_IP, timeout, buffer, options);
            if (reply.Status == IPStatus.Success)
            {
                return true;

            }
            return false;
        }
        void ServerOk_Click(object sender, TomShane.Neoforce.Controls.EventArgs e)
        {
            if (serverSelect._currentSelect.Status.Text.ToLower() == "online")
            {


                string lastIp = client.IP;
                int lastport = client.Port;
                //Engine.Client.BaseClient newCl = new Engine.Client.BaseClient(serverSelect._currentSelect.IP, serverSelect._currentSelect.Port);
                client.SetIPandPort(serverSelect._currentSelect.IP, serverSelect._currentSelect.Port);
                client.Reconnect();
                //newCl.Start();
                if (client.Connected)
                {
                    Engine.NetClasses.RequestGame req = (Engine.NetClasses.RequestGame)Engine.NetClasses.NetPacket.GetPacket((byte)Engine.NetClasses.PacketType.RequestGame);
                    Engine.NetClasses.PacketsBilder pb = new Engine.NetClasses.PacketsBilder(req);
                    client.SetFromClient(pb);
                    serverSelect.Hide();
                    LoginServerState.Hide();
                    //  client.ShutDown();
                    // client = newCl;
                    // NOWAEngine dd = (NOWAEngine)Game;
                    // dd.BaseInputManager.GetNetClient = client;
                }
                else
                {
                    client.SetIPandPort(lastIp, lastport);
                    client.Reconnect();
                    serverSelect.Hide();
                    loginform.Show();
                }
            }
        }
        void TryConnectLogin()
        {
            try
            {
                NOWAEngine dd = (NOWAEngine)Game;
                client = dd.BaseInputManager.GetNetClient;
                if (client.Connected == false)
                {
                    string strHostName = Dns.GetHostName();
                    IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);
                   bool ping=false;
                    IPAddress[] addr = Dns.GetHostAddresses(strHostName);
                    string ipadr = "";
                    for (int i = 0; i < addr.Length; i++)
                    {
                        if (addr[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                        {
                            ipadr = addr[i].ToString();
                            if (pingServer(addr[i]))
                             {
                                 ping = true;
                            }
                            break;
                        }
                    }
                    if (ping)
                    {
                         client.SetIPandPort(ipadr, 7777);
                    client.Start();
                    }
                   
                }
            }
            catch (Exception e)
            {

               // Console.WriteLine("not connect error{0}", e.Message);
            }

        }
        void LoginBox_Click(object sender, TomShane.Neoforce.Controls.EventArgs e)
        {
            loginform.LoginBox.TextColor = Microsoft.Xna.Framework.Color.Black;
            loginform.PassBox.TextColor = Microsoft.Xna.Framework.Color.Black;
        }

        void PassBox_Click(object sender, TomShane.Neoforce.Controls.EventArgs e)
        {
            loginform.LoginBox.TextColor = Microsoft.Xna.Framework.Color.Black;
            loginform.PassBox.TextColor = Microsoft.Xna.Framework.Color.Black;
        }

        void CancelBtn_Click(object sender, TomShane.Neoforce.Controls.EventArgs e)
        {
            client.ssesionKey = 0;
            eula.Hide();
            loginform.Show();
        }
        void okBtn_Click(object sender, TomShane.Neoforce.Controls.EventArgs e)
        {
            if (client.Connected != false)
            {
                Engine.NetClasses.RequestServerList req = (Engine.NetClasses.RequestServerList)Engine.NetClasses.NetPacket.GetPacket((byte)Engine.NetClasses.PacketType.RequestServerList);




                Engine.NetClasses.PacketsBilder pb = new Engine.NetClasses.PacketsBilder(req);
                client.SetFromClient(pb);
                eula.Hide();
            }
        }
        void Cancelbtn_Click(object sender, TomShane.Neoforce.Controls.EventArgs e)
        {
            Game.Exit();
        }
        void Okbtn_Click(object sender, TomShane.Neoforce.Controls.EventArgs e)
        {


            if (client.Connected != false)
            {
                Engine.NetClasses.RequestLoginAuth req = (Engine.NetClasses.RequestLoginAuth)Engine.NetClasses.NetPacket.GetPacket(3);
                req.SetLoginAndPass(loginform.LoginBox.Text, loginform.PassBox.Text);
                Engine.NetClasses.PacketsBilder pb = new Engine.NetClasses.PacketsBilder(req);
                client.SetFromClient(pb);
                loginform.Hide();
                //eula.Show();
            }


        }
        public override void Update(Microsoft.Xna.Framework.GameTime gameTime)
        {
            if (client != null)
            {


                if (client.Connected)
                {
                    LoginServerState.TextColor = Microsoft.Xna.Framework.Color.Green;
                    LoginServerState.Text = "Login server ONLINE";
                    loginform.Okbtn.Enabled = true;
                }
                else
                {
                    eula.Hide();
                    serverSelect.Hide();
                    loginform.Show();
                    LoginServerState.Text = "Login server OFFLINE";
                    LoginServerState.TextColor = Microsoft.Xna.Framework.Color.Red;
                    loginform.Okbtn.Enabled = false;
                    if (cServ > 3000)
                    {
                        TryConnectLogin();
                        cServ = 0;
                    }
                    else
                    {
                        cServ++;
                    }

                }
                if (client.CountFromServer > 0)
                {
                    Engine.NetClasses.PacketsBilder[] tmp = client.GetFromServer();
                    for (int i = 0; i < tmp.Length; i++)
                    {
                        switch (tmp[i].Header.TypePacket)
                        {
                            case Engine.NetClasses.PacketType.NullPacket:
                                break;
                            case Engine.NetClasses.PacketType.Init:
                                break;
                            case Engine.NetClasses.PacketType.LoginOk:
                                Engine.NetClasses.LoginOk lOk = tmp[i].getStryct();
                                byte[] tmps = new byte[8];
                                eula.Show();
                                Array.Copy(BitConverter.GetBytes(lOk.Frist), 0, tmps, 0, 4);
                                Array.Copy(BitConverter.GetBytes(lOk.Secondory), 0, tmps, 4, 4);
                                client.ssesionKey = BitConverter.ToUInt64(tmps, 0);
                                break;
                            case Engine.NetClasses.PacketType.RequestLoginAuth:
                                break;
                            case Engine.NetClasses.PacketType.LoginFail:
                                eula.Hide();
                                loginform.Show();
                                Engine.NetClasses.LoginFail lfail = tmp[i].getStryct();
                                switch (lfail.FailCode)
                                {
                                    case 1:
                                        loginform.LoginBox.TextColor = Microsoft.Xna.Framework.Color.Red;
                                        break;
                                    case 2:
                                        loginform.PassBox.TextColor = Microsoft.Xna.Framework.Color.Red;
                                        break;

                                    default:
                                        loginform.LoginBox.TextColor = Microsoft.Xna.Framework.Color.Red;
                                        loginform.PassBox.TextColor = Microsoft.Xna.Framework.Color.Red;
                                        break;
                                }
                                break;
                            case Engine.NetClasses.PacketType.NetPing:
                                break;
                            case Engine.NetClasses.PacketType.RequestServerList:
                                break;
                            case Engine.NetClasses.PacketType.ServerList:
                                Engine.NetClasses.ListServer servList = tmp[i].getStryct();
                                Engine.NetClasses.ServersList[] Lists = servList.GetArray();
                                if (Lists != null)
                                {
                                    for (int sI = 0; sI < Lists.Length; sI++)
                                    {
                                        ServerItem item = new ServerItem(GUIManager);
                                        item.NameServer.Text = Lists[sI].ServerName;
                                        item.ID.Text = sI.ToString();
                                        item.IP = Lists[sI].IpServer;
                                        item.Port = Lists[sI].PortServer;
                                        if (Lists[sI].Online)
                                        {
                                            item.Status.Text = "Online";
                                            item.Status.TextColor = Microsoft.Xna.Framework.Color.Green;
                                        }
                                        else
                                        {
                                            item.Status.Text = "Offline";
                                            item.Status.TextColor = Microsoft.Xna.Framework.Color.Red;
                                        }
                                        item.Top = 0 + (sI * 25);
                                        item.Left = 0;
                                        item.SetSize(387, 20);
                                        item.Init();
                                        item.Parent = serverSelect.list;

                                        serverSelect.AddInList(item);
                                        //  serverSelect.list.Items.Add();
                                    }



                                    // serverSelect.list.Init();
                                    serverSelect.Show();
                                    // serverSelect.list.Refresh();
                                }
                                else
                                {
                                    serverSelect.Hide();
                                    loginform.Show();
                                }
                                break;
                            default:
                                break;
                        }

                    }
                }

            }
            else
            {
                //  eula.Hide();
                // serverSelect.Hide();
                loginform.Show();
                LoginServerState.Text = "Login server OFFLINE";
                LoginServerState.TextColor = Microsoft.Xna.Framework.Color.Red;
                loginform.Okbtn.Enabled = false;
            }
            base.Update(gameTime);
        }


        public static LoginScene ActionCreate(NOWAEngine _game)
        {
            return new LoginScene(_game);
        }





    }
}
